package cn.wolfcode.util;

import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.Test;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;

public class PoiTest {
    // 03 版本的 Excel导出
    @Test
    public void testWrite03() throws Exception{
//        1、创建一个 workbook（新的 Excel工作簿）；
        HSSFWorkbook workbook = new HSSFWorkbook();
//        2、创建一个sheet（工作表），通过 workbook调用；
        Sheet sheet = workbook.createSheet("疫苗接种人数");
//        3、创建行 row（行要从0开始）；
        Row row = sheet.createRow(0);
//        4、创建单元格，要给单元格设置值；
//        两种方式，一普通方式
//        Cell cell = row.createCell(0);
//        cell.setCellValue("今日人数");
//        Cell cell1 = row.createCell(1);
//        cell1.setCellValue("666");
//        链式调用
        row.createCell(0).setCellValue("今日人数");
        row.createCell(1).setCellValue("666");

        Row row1 = sheet.createRow(1);
        row1.createCell(0).setCellValue("统计时间");
        row1.createCell(1).setCellValue(new Date().toLocaleString());
        //导出路径加上表的格式
        FileOutputStream fileOutputStream = new FileOutputStream("E:\\Program Files\\疫苗接种人数.xls");
//        5、把创建的表格导出到磁盘中
        workbook.write(fileOutputStream);
        // 关闭流
        fileOutputStream.close();
        workbook.close();
    }

    // 07 版本的Excel导出
    @Test
    public void testWrite07() throws Exception{
        // 创建一个新的 workbook
        XSSFWorkbook workbook = new XSSFWorkbook();
        // 创建一个 sheet
        Sheet sheet = workbook.createSheet();
        // 创建行 row
        Row row = sheet.createRow(0);
        // 创建单元格，设置单元格的值
        row.createCell(0).setCellValue("今日人数");
        row.createCell(1).setCellValue("888");
        // 创建第二行 row
        Row row1 = sheet.createRow(1);
        // 设置单元格的值
        row1.createCell(0).setCellValue("统计时间");
        row1.createCell(1).setCellValue(new Date().toLocaleString());
        // 导出路径和设置表的格式
        FileOutputStream fileOutputStream = new FileOutputStream("E:\\Program Files\\疫苗接种人数07.xlsx");
        // 把文件写到磁盘中
        workbook.write(fileOutputStream);
        // 关闭资源
        fileOutputStream.close();
        workbook.close();
    }

    // 大文件写入(03版本)
    @Test
    public void testWrite03BigData() throws Exception {
        // 记录开始时间
        long begin = System.currentTimeMillis();
        // 创建一个 workbook
        Workbook workbook = new HSSFWorkbook();
        // 创建一个sheet
        Sheet sheet = workbook.createSheet();
        // xls 文件最大支持65536 行
        for (int rowNum = 0; rowNum < 65536; rowNum++) {
            // 创建一个行row
            Row row = sheet.createRow(rowNum);
            //创建单元格
           for (int cellNum = 0; cellNum < 10; cellNum++) {
                Cell cell = row.createCell(cellNum);
                cell.setCellValue(cellNum);
            }
        }
        System.out.println("done");
        FileOutputStream out = new FileOutputStream("E:\\Program Files\\疫苗接种人数大文件03.xls");
        workbook.write(out);
        // 操作结束，关闭文件
        out.close();

        // 记录时间
        long end = System.currentTimeMillis();
        System.out.println((double)(end-begin)/1000);   // 2.585
    }

    // 大文件写入(07版本)
    @Test
    public void testWrite07BigData() throws IOException {
        // 记录时间
        long begin = System.currentTimeMillis();
        // 创建一个 workboot
        Workbook workbook = new XSSFWorkbook();
        // 创建一个 sheet
        Sheet sheet = workbook.createSheet();
        // 创建一个行 row，xlsx支持20万条数据
        for (int rowNum = 0; rowNum < 66666; rowNum++) {
            Row row = sheet.createRow(rowNum);
            // 创建单元格
            for (int cellNum = 0; cellNum < 5; cellNum++) {
                Cell cell = row.createCell(cellNum);
                cell.setCellValue(cellNum);
            }
        }
        System.out.println("done");
        FileOutputStream out = new FileOutputStream("E:\\Program Files\\疫苗接种人数大文件07.xlsx");
        workbook.write(out);
        // 操作结束，关闭文件
        out.close();
        // 记录时间
        long end = System.currentTimeMillis();
        System.out.println((double)(end-begin)/1000);   //6.005
    }

    @Test
    public void testWrite07BigDataFast() throws IOException {
        //记录开始时间
        long begin = System.currentTimeMillis();
        // 创建一个 SXSSFWorkbook
        SXSSFWorkbook workbook = new SXSSFWorkbook();
        // 创建一个 sheet
        Sheet sheet = workbook.createSheet();
        // 创建一个行 row，xlsx支持20万条数据
        for (int rowNum = 0; rowNum < 66680; rowNum++) {
            Row row = sheet.createRow(rowNum);
            // 创建单元格
            for (int cellNum = 0; cellNum < 3; cellNum++) {
                Cell cell = row.createCell(cellNum);
                cell.setCellValue(cellNum);
            }
        }
        System.out.println("done");
        FileOutputStream out = new FileOutputStream("E:\\Program Files\\疫苗接种人数大文件07fast.xlsx");
        workbook.write(out);
        // 操作结束，关闭文件
        out.close();
        // 清除临时文件
        ((SXSSFWorkbook)workbook).dispose();
        // 记录时间
        long end = System.currentTimeMillis();
        System.out.println((double)(end-begin)/1000);       //3.211
    }

    // Excel 2003版本读功能
    @Test
    public void testRead03() throws Exception {
        //1、先 new 一个 FileInputStream 读取磁盘中的文件的路径
        FileInputStream inputStream = new FileInputStream("E:\\Program Files\\疫苗接种人数.xls");
        //2、使用workbook 去读取磁盘中文件
        Workbook workbook = new HSSFWorkbook(inputStream);
        Sheet sheet = workbook.getSheetAt(0);
        //3、获取sheet，getSheet是根据索引去拿到 sheet 页
        for (int i = 0; i <= sheet.getLastRowNum(); i++) {  // i 要小于等于才能获取到全部信息
            Row row = sheet.getRow(i);
            //4、遍历单元格
            for (int j = 0; j < row.getLastCellNum(); j++) {    // j 不必小于等于
                String stringCellValue = row.getCell(j).getStringCellValue();
                System.out.println(stringCellValue);
            }
        }
        // 关闭资源
        workbook.close();
        inputStream.close();
    }

    // Excel 2007版本读功能
    @Test
    public void testRead07() throws Exception {
        //1、先 new 一个 FileInputStream 读取磁盘中的文件的路径
        FileInputStream fileInputStream = new FileInputStream("E:\\Program Files\\疫苗接种人数07.xlsx");
        //2、使用workbook 去读取磁盘中文件
        Workbook workbook = new XSSFWorkbook(fileInputStream);
        Sheet sheet = workbook.getSheetAt(0);
        //3、获取sheet，getSheet是根据索引去拿到 sheet 页
        for (int i = 0; i <= sheet.getLastRowNum(); i++) {  // i 要小于等于才能获取到全部信息
            Row row = sheet.getRow(i);
            //4、遍历单元格
            for (int j = 0; j < row.getLastCellNum(); j++) {    // j 不必小于等于
                String stringCellValue = row.getCell(j).getStringCellValue();
                System.out.println(stringCellValue);
            }
        }
        // 关闭资源
        workbook.close();
        fileInputStream.close();
    }

    // 读取不同类型的数据
    @Test
    public void testCellType() throws Exception {
        //先 new 一个 FileInputStream 读取磁盘中的文件的路径
        FileInputStream fileInputStream = new FileInputStream("E:\\Program Files\\商品信息表.xlsx");
        //使用workbook 去读取磁盘中文件
        Workbook workbook = new XSSFWorkbook(fileInputStream);
        // 获取sheet
        Sheet sheet = workbook.getSheetAt(0);
        //读取商品列表数据
        Row row = sheet.getRow(1);
        for (int i = 0; i < row.getLastCellNum(); i++) {
            // 根据单元格类型去取值
            Cell cell = row.getCell(i);
            if (cell.getCellType().equals(CellType.STRING)) {
                System.out.println("STRING类型值为："+ cell.getStringCellValue());
            }else if (cell.getCellType().equals(CellType.BOOLEAN)){
                System.out.println("BOOLEAN类型值为："+cell.getBooleanCellValue());
            }else if (cell.getCellType().equals(CellType.NUMERIC)){
                // 判断单元格是否是日期类型
                if (DateUtil.isCellDateFormatted(cell)) {
                    System.out.println("DATE类型值为："+cell.getDateCellValue());
                }else {
                    System.out.println("NUMBER类型值为："+cell.getNumericCellValue());
                }
            }else if (cell.getCellType().equals(CellType.BLANK)){
                System.out.println("BLANK类型值为：");
            }else {
                System.out.println("其他类型:");
            }
        }
        // 关闭资源
        workbook.close();
        fileInputStream.close();
    }
}
